import axios, {
    type AxiosInstance,
    type AxiosRequestConfig,
    type AxiosResponse,
    type InternalAxiosRequestConfig
} from "axios";
import {getToken} from "@/utils/index.ts";
import type {ResponseType} from "@/types/httpRequest.ts";
import {notification} from "antd";

class Request {
    private instance: AxiosInstance

    constructor(config: AxiosRequestConfig) {
        this.instance = axios.create(config)

        this.interceptors()
    }

    private interceptors () {
        this.instance.interceptors.request.use(
            (config: InternalAxiosRequestConfig) => {
                const token = getToken()
                if (token) {
                    config.headers['Authorization'] = token
                }

                return config
            },
            (err) => {
                return Promise.reject(err)
            }
        )
        this.instance.interceptors.response.use(
            (res: AxiosResponse) => {
                if (res.status >= 200 && res.status < 300) {
                    if (res.headers['content-type'] === 'application/octet-stream') {
                        return res.data
                    }
                    if (res.data.code === 200) {
                        return res.data
                    }
                }
                notification.error({
                    message: res.data.msg,
                    duration: 10,
                    showProgress: true,
                })
                return Promise.reject(res.data)
            },
            (err) => {
                console.log(err)
                return Promise.reject(err)
            }
        )
    }
    public get<T = unknown>(url: string, config?: AxiosRequestConfig): Promise<ResponseType<T>> {
        return this.instance.get(url, config)
    }
    public post<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<ResponseType<T>> {
        return this.instance.post(url, data, config)
    }
    public put<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<ResponseType<T>> {
        return this.instance.put(url, data, config)
    }
    public delete<T = unknown>(url: string, params?: unknown): Promise<ResponseType<T>> {
        return this.instance.delete(url, { params })
    }
    public download(url: string, params?: unknown): Promise<Blob> {
        return this.instance.get(url, { params, responseType: 'blob' })
    }
}

const httpRequest = new Request({
    baseURL: import.meta.env.VITE_API_BASE_URL
})

export default httpRequest